package com.frikinet.lifeguard.gui;

import java.awt.BorderLayout;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JPanel;

import org.lobobrowser.html.HtmlRendererContext;
import org.w3c.dom.html2.HTMLElement;
import org.w3c.dom.html2.HTMLLinkElement;

import ch.lambdaj.Lambda;
import ch.lambdaj.function.convert.Converter;

import com.frikinet.lifeguard.App;
import com.frikinet.lifeguard.events.UserSelectedEvent;
import com.frikinet.lifeguard.events.UserSelectedListener;
import com.frikinet.lifeguard.events.YearMonthSelectedEvent;
import com.frikinet.lifeguard.model.Post;
import com.frikinet.lifeguard.model.User;
import com.frikinet.lifeguard.util.Day;
import com.frikinet.lifeguard.util.HibernateUtil;
import com.frikinet.lifeguard.util.Year;

public class UserHtmlPanel extends JPanel implements UserSelectedListener
{
	private static final long serialVersionUID = 1L;
	
	private TemplateHtmlPanel htmlPanel;
	
	public UserHtmlPanel()
	{
		super(new BorderLayout());
		
		App.events.addUserSelectedListener(this);
		
		buildGUI();
	}
	
	private void buildGUI()
	{
		htmlPanel = new TemplateHtmlPanel(new YearLinkBehaviour());
		add(htmlPanel, BorderLayout.CENTER);
	}
	
	@Override
	public void userSelected(UserSelectedEvent event)
	{
		Map<String, Object> context = new HashMap<String, Object>();
		
		Map<String, Post> posts = new HashMap<String, Post>();
		for(Post post: event.getUser().getPosts())
		{
			posts.put(Day.DAY_ID_FORMAT.format(post.getDate()), post);
		}
		context.put("posts", posts);
		
		SortedSet<Integer> yearsAvailable = new TreeSet<Integer>(Lambda.convert(event.getUser().getPosts(), new Converter<Post, Integer>() {
			@Override
			public Integer convert(Post post)
			{
				Calendar c = Calendar.getInstance();
				c.setTime(post.getDate());
				return c.get(Calendar.YEAR);
			}
		}));
		
		List<Year> years = Lambda.convert(yearsAvailable, new Converter<Integer, Year>() {
			@Override
			public Year convert(Integer year)
			{
				return new Year(year);
			}
		});

		context.put("user", event.getUser());
		context.put("years", years);
		
		htmlPanel.navigate("user", context);
	}
	
	public class YearLinkBehaviour extends HtmlBehaviourAdapter
	{
		private final Pattern linkPattern = Pattern.compile("^(.*?)/(\\d{4})$");
		@Override
		public boolean checkElement(HTMLElement element)
		{
			return element instanceof HTMLLinkElement;
		}

		@Override
		public void performLinkClicked(HtmlRendererContext renderer, HTMLElement element, URL url, String target)
		{
			Matcher matcher = linkPattern.matcher(((HTMLLinkElement)element).getAttribute("href"));
			if(matcher.find())
			{
				User user = HibernateUtil.get(User.class, "name", matcher.group(1));
				if(user != null)
				{
					App.events.fireYearSelected(new YearMonthSelectedEvent(this, user, new Integer(matcher.group(2))));
				}
			}
		}
		
	}
}
